package sm.upgrade.api.impl;

import java.sql.SQLException;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;

import sm.dam.api.DBDictService;
import sm.dbdict.def.DBDict;
import sm.hibernate.DAMUtil;
import sm.upgrade.api.DataService;
import sm.util.SMMap;

public class DataServiceImpl implements DataService {

	private HibernateTemplate template;

	public void setTemplate(HibernateTemplate template) {
		this.template = template;
	}

	@Override
	public DBDict getDBDict(String fileName) {
		DBDict des = null;
		Object dbdict = template.get(DBDictService.DBDICT, fileName);
		if (dbdict != null) {
			SMMap dbdictMap = (SMMap) dbdict;
			des = (DBDict) dbdictMap.get(DBDictService.DESCRIPTOR);
		}
		return des;
	}

	private void initializeArray(List<SMMap> list, String... joinedArrays) {
		if (joinedArrays != null && joinedArrays.length > 0 && list != null) {
			for (SMMap data : list) {
				for (String joinedArray : joinedArrays) {
					Object joinedArrayValue = data.get(joinedArray);
					Hibernate.initialize(joinedArrayValue);
				}
			}
		}
	}

	@Override
	public List<SMMap> getDatasByKey(final String entityName,
			final String[] keyPaths, final Object[] keyValues,
			String... joinedArrays) {
		List<SMMap> list = DAMUtil.getDatasByKey(template, entityName,
				keyPaths, keyValues);
		initializeArray(list, joinedArrays);
		return list;
	}

	@Override
	public List<SMMap> getNextBatchDatas(final String entityName,
			final int firstResult, final int maxResults, String... joinedArrays) {
		List<SMMap> list = (List<SMMap>) template
				.execute(new HibernateCallback() {
					@Override
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						Criteria criteria = session.createCriteria(entityName);
						criteria.setFirstResult(firstResult);
						if (maxResults != 0) {
							criteria.setMaxResults(maxResults);
						}
						return criteria.list();
					}
				});

		initializeArray(list, joinedArrays);

		return list;
	}

}
